﻿#pragma once
#include "yzrutil.h"

namespace yzrilyzr_lang{
	template<typename T>
	class U_EXPORT_API Boxing :public BaseObject{
		public:
		T value;
		Boxing(){}
		Boxing(T val) :value(val){}
		Boxing<T> operator+(const Boxing<T> &other)const{
			return value + other.value;
		}
		Boxing<T> operator-(const Boxing<T> &other)const{
			return value - other.value;
		}
		Boxing<T> operator*(const Boxing<T> &other)const{
			return value * other.value;
		}
		Boxing<T> operator/(const Boxing<T> &other)const{
			return value / other.value;
		}
		Boxing<T> & operator+=(const Boxing<T> &other){
			value+=other.value;
			return *this;
		}
		Boxing<T> & operator-=(const Boxing<T> &other){
			value-=other.value;
			return *this;
		}
		Boxing<T> & operator*=(const Boxing<T> &other){
			value*=other.value;
			return *this;
		}
		Boxing<T> & operator/=(const Boxing<T> &other){
			value/=other.value;
			return *this;
		}
		bool operator==(const Boxing<T> &other)const{
			return value == other.value;
		}
		bool operator!=(const Boxing<T> &other)const{
			return value != other.value;
		}
		bool operator>(const Boxing<T> &other)const{
			return value > other.value;
		}
		bool operator<(const Boxing<T> &other)const{
			return value < other.value;
		}
	};
	EBCLASS(Number){
		public:
		Number()=default;
		virtual int8_t byteValue()const=0;
		virtual int16_t shortValue()const=0;
		virtual int32_t intValue()const=0;
		virtual int64_t longValue()const=0;
		virtual float floatValue()const=0;
		virtual double doubleValue()const=0;
	};
	ECLASS(Integer, public Number, public Boxing<int32_t>){
		public:
		Integer(int32_t value) :Boxing(value){}
		int8_t byteValue()const{
			return (int8_t)value;
		}
		int16_t shortValue()const{
			return (int16_t)value;
		}
		int32_t intValue()const{
			return (int32_t)value;
		}
		int64_t longValue()const{
			return (int64_t)value;
		}
		float floatValue()const{
			return (float)value;
		}
		double doubleValue()const{
			return (double)value;
		}
	};
	ECLASS(Short, public Number, public Boxing<int16_t>){
		public:
		Short(int16_t value) :Boxing(value){}
		int8_t byteValue()const{
			return (int8_t)value;
		}
		int16_t shortValue()const{
			return (int16_t)value;
		}
		int32_t intValue()const{
			return (int32_t)value;
		}
		int64_t longValue()const{
			return (int64_t)value;
		}
		float floatValue()const{
			return (float)value;
		}
		double doubleValue()const{
			return (double)value;
		}
	};
	ECLASS(Long, public Number, public Boxing<int64_t>){
		public:
		Long(int64_t value) :Boxing(value){}
		int8_t byteValue()const{
			return (int8_t)value;
		}
		int16_t shortValue()const{
			return (int16_t)value;
		}
		int32_t intValue()const{
			return (int32_t)value;
		}
		int64_t longValue()const{
			return (int64_t)value;
		}
		float floatValue()const{
			return (float)value;
		}
		double doubleValue()const{
			return (double)value;
		}
	};
	ECLASS(Float, public Number, public Boxing<float>){
		public:
		Float(float value) :Boxing(value){}
		int8_t byteValue()const{
			return (int8_t)value;
		}
		int16_t shortValue()const{
			return (int16_t)value;
		}
		int32_t intValue()const{
			return (int32_t)value;
		}
		int64_t longValue()const{
			return (int64_t)value;
		}
		float floatValue()const{
			return (float)value;
		}
		double doubleValue()const{
			return (double)value;
		}
	};
	ECLASS(Double, public Number, public Boxing<double>){
		public:
		Double(double value) :Boxing(value){}
		int8_t byteValue()const{
			return (int8_t)value;
		}
		int16_t shortValue()const{
			return (int16_t)value;
		}
		int32_t intValue()const{
			return (int32_t)value;
		}
		int64_t longValue()const{
			return (int64_t)value;
		}
		float floatValue()const{
			return (float)value;
		}
		double doubleValue()const{
			return (double)value;
		}
	};
}